<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>03-promise基本使用</title>
</head>

<body>
  <script>
    // 1. 创建 Promise 实例对象(pending 状态), 指定执行器函数
    const p = new Promise((resolve, reject) => {
      // 2. 在执行器函数中启动异步任务
      console.log('异步任务启动---');
      /* setTimeout(() => {
        console.log('异步任务开始执行---');
        const time = Date.now() // 假设: 时间为奇数代表成功, 为偶数代表失败
        if (time % 2 === 1)
        { // 成功了
          // 3. 1. 如果成功了, 调用 resolve()并传入成功的 value
          resolve('time为偶数 ' + time)
        } else
        { // 失败了
          // 3.2. 如果失败了, 调用 reject()并传入失败的 reason
          reject('time为奇数 ' + time)
        }
      }, 2000) */
      // 发送ajax请求
      // 1) 创建 XMLHttpRequest 实例对象
      const xhr = new XMLHttpRequest();
      // 2) 初始化 设置请求方法和 url
      xhr.open('get', 'https://api.github.com/search/users?q="promise"');
      // xhr.responseType = 'json';  //设置接收的内容为json格式
      // 3) 发送请求
      xhr.send();   //get 请求不传 body 参数，只有 post 请求使用
      //4) 事件绑定 处理服务端返回的结果
      xhr.onreadystatechange = function () {
        //判断 (服务端返回了所有的结果)
        if (xhr.readyState === 4)
        {
          //判断响应状态码 200  404  403 401 500
          // 2xx 成功
          if (xhr.status >= 200 && xhr.status < 300)
          {
            // 请求成功, 调用 resolve(value)
            resolve(xhr.response)
          } else
          {
            // 请求失败, 调用 reject(reason)
            reject(`请求失败--status: ${xhr.status}`)
          }
        }
      }
    })
    //4. 调用then()为Promise 实例对象指定成功或失败的回调函数来获取成功的 vlaue 或失败的 reason
    const result = p.then(
      (value) => { console.log(`成功的回调函数-异步，成功的value：${value}`); },
      (reason) => { console.log(`失败的回到函数-异步，失败原因：${reason}`); }
    )

    /* //同一个Promise实例对象多次调用then函数，不会覆盖掉前面的，而是每次都会执行其中的成功/失败回调，且每次的状态和接收到的值都一样
    p.then(
      (value) => { console.log(`第二次执行then，成功的value：${value}`); },
      (reason) => { console.log(`第二次执行then，失败原因：${reason}`); }
      ) */

    // console.log(result);  // then返回的是一个新的 Promise实例对象
    /* then的返回值：
      当一个 Promise 完成（fulfilled）或者失败（rejected）时，返回函数将被异步调用（由当前的线程循环来调度完成）。
      具体的返回值依据以下规则返回。如果 then 中的回调函数：

        1.返回了一个值，那么 then 返回的 Promise 将会成为 fulfilled 状态，并且将返回的值作为 fulfilled 状态的回调函数的参数值。

        2.没有返回任何值，那么 then 返回的 Promise 将会成为 fulfilled 状态，并且该 fulfilled 状态的回调函数的参数值为 undefined。

        3.抛出一个错误，那么 then 返回的 Promise 将会成为 rejected 状态，并且将抛出的错误作为 rejected 状态的回调函数的参数值。

        4.返回一个已经是 fulfilled 状态的 Promise，那么 then 返回的 Promise 也会成为 fulfilled 状态，并且将那个 Promise 的 fulfilled 状态的回调函数的参数值作为该被返回的 Promise 的 fulfilled 状态回调函数的参数值。

        5.返回一个已经是 rejected 状态的 Promise，那么 then 返回的 Promise 也会成为 rejected 状态，并且将那个 Promise 的 rejected 状态的回调函数的参数值作为该被返回的 Promise 的 rejected 状态回调函数的参数值。

        6.返回一个未定状态（pending）的 Promise，那么 then 返回 Promise 的状态也是未定的，并且它的终态与那个 Promise 的终态相同；同时，它变为终态时调用的回调函数参数与那个 Promise 变为终态时的回调函数的参数是相同的。
    */

    console.log('主线程代码执行--'); 
  </script>
</body>

</html>